#include "conversion.h"

Vector::Vector()
{
    n = 0;
    vec = 0;
}

Vector::Vector(complexd* begin, complexd* end)
{
    vec = begin;
    for (n = 0; begin < end; n++, begin++)
        ;
}

Vector::Vector(int nt, complexd* vector)
{
    n = nt;
    vec = new complexd [n];
    for (int i = 0; i < n; i++)
        vec[i] = vector[i];
}

Vector::Vector(const Vector &vector)
{
    n = vector.n;
    vec = new complexd [n];
    for (int i = 0; i < n; i++)
        vec[i] = vector.vec[i];
}

Vector::~Vector()
{
    delete [] vec;
}


void Conversion::doNoize()
{
    complexd *new_vec = new complexd [4];
    complexd *old_vec = new complexd [4];
    double phi = 0;

    if (shmem_my_pe() == 0)
        phi = normal_dis_gen();
    shmem_double_toall(&phi, 0);
    shmem_barrier_all();

    old_vec[0] = vec[0][0];
    old_vec[1] = vec[0][1];
    old_vec[2] = vec[1][0];
    old_vec[3] = vec[1][1];

    new_vec[0] = old_vec[0] * cos(phi) - old_vec[1] * sin(phi);
    new_vec[1] = old_vec[0] * sin(phi) + old_vec[1] * cos(phi);
    new_vec[2] = old_vec[2] * cos(phi) - old_vec[3] * sin(phi);
    new_vec[3] = old_vec[2] * sin(phi) + old_vec[3] * cos(phi);

    vec[0][0] = new_vec[0];
    vec[0][1] = new_vec[1];
    vec[1][0] = new_vec[2];
    vec[1][1] = new_vec[3];

}


complexd Vector::operator[](int l)
{
    if (l >= n) {
        cerr << "Nooo 2 :(" << endl;
        exit(2);
    }
    return vec[l];
}

Vector Vector::operator=(Vector vector)
{
    n = vector.n;
    delete [] vec;
    vec = new complexd [n];
    for (int i = 0; i < n; i++)
        vec[i] = vector.vec[i];
    return *this;
}

ostream& operator<<(ostream &stream, Vector &vec)
{
    for (int i = 0; i < vec.n; i++)
        stream << vec[i] << " ";
    stream << endl;
    return stream;
}

Conversion::Conversion(int mt, int n, complexd* vector)
{
    m = mt;
    vec = new Vector [m];
    for (int i = 0; i < m; i++)
        vec[i] = Vector(n, vector + i * n);
    return;
}

Conversion::Conversion(const Conversion &conversion)
{
    m = conversion.m;
    vec = new Vector [m];
    for (int i = 0; i < m; i++)
        vec[i] = conversion.vec[i];
}

Conversion::~Conversion()
{
    delete [] vec;
}

Vector Conversion::operator[](int k)
{
    if (k >= m) {
        cerr << "Nooo 1 :(" << endl;
        exit(2);
    }
    return vec[k];
}

ostream& operator<<(ostream &stream, Conversion &con)
{
    Vector a;
    for (int i = 0; i < con.m; i++) {
        a = con[i];
        stream << a;
    }
    return stream;
}


double Conversion::normal_dis_gen()
{
    double S = 0.;
    for (int i = 0; i < 12; i++)
        S += (double)rand()/RAND_MAX;
    return S - 6;
}
